"""
文件上传相关API路由
"""
import os
import io
import uuid
from pathlib import Path
from fastapi import APIRouter, UploadFile, File, HTTPException
from fastapi.responses import JSONResponse
from typing import List
from app.config import settings
from PIL import Image

router = APIRouter()

# 允许的图片类型
ALLOWED_EXTENSIONS = {'.jpg', '.jpeg', '.png', '.gif', '.webp'}
# 最大文件大小（10MB）
MAX_FILE_SIZE = settings.MAX_UPLOAD_SIZE


def ensure_upload_dir():
    """确保上传目录存在"""
    upload_dir = Path(settings.UPLOAD_DIR)
    upload_dir.mkdir(parents=True, exist_ok=True)
    return upload_dir


def validate_image(file: UploadFile) -> None:
    """验证图片文件"""
    # 检查文件扩展名
    file_ext = Path(file.filename).suffix.lower()
    if file_ext not in ALLOWED_EXTENSIONS:
        raise HTTPException(
            status_code=400,
            detail=f"不支持的文件类型。允许的类型: {', '.join(ALLOWED_EXTENSIONS)}"
        )
    
    # 检查文件大小（如果文件已读取）
    if hasattr(file, 'size') and file.size > MAX_FILE_SIZE:
        raise HTTPException(
            status_code=400,
            detail=f"文件大小超过限制（最大 {MAX_FILE_SIZE / 1024 / 1024:.1f}MB）"
        )


@router.post("/upload")
async def upload_file(file: UploadFile = File(...)):
    """
    上传单个文件
    
    - **file**: 要上传的文件
    """
    try:
        # 验证文件
        validate_image(file)
        
        # 确保上传目录存在
        upload_dir = ensure_upload_dir()
        
        # 生成唯一文件名
        file_ext = Path(file.filename).suffix.lower()
        unique_filename = f"{uuid.uuid4().hex}{file_ext}"
        file_path = upload_dir / unique_filename
        
        # 读取文件内容
        contents = await file.read()
        
        # 检查文件大小
        if len(contents) > MAX_FILE_SIZE:
            raise HTTPException(
                status_code=400,
                detail=f"文件大小超过限制（最大 {MAX_FILE_SIZE / 1024 / 1024:.1f}MB）"
            )
        
        # 验证是否为有效图片（使用PIL）
        try:
            image = Image.open(io.BytesIO(contents))
            image.verify()  # 验证图片
        except Exception:
            raise HTTPException(status_code=400, detail="无效的图片文件")
        
        # 重新打开图片（verify后需要重新打开）
        image = Image.open(io.BytesIO(contents))
        
        # 可选：压缩图片（如果太大）
        max_dimension = 2000  # 最大尺寸
        if max(image.size) > max_dimension:
            image.thumbnail((max_dimension, max_dimension), Image.Resampling.LANCZOS)
            # 保存压缩后的图片
            image.save(file_path, optimize=True, quality=85)
        else:
            # 直接保存
            with open(file_path, "wb") as f:
                f.write(contents)
        
        # 返回文件URL（相对于静态文件路径）
        file_url = f"/uploads/{unique_filename}"
        
        return {
            "url": file_url,
            "filename": unique_filename,
            "original_filename": file.filename,
            "size": len(contents)
        }
        
    except HTTPException:
        raise
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"上传失败: {str(e)}")


@router.post("/upload/multiple")
async def upload_multiple_files(files: List[UploadFile] = File(...)):
    """
    上传多个文件
    
    - **files**: 要上传的文件列表（最多10个）
    """
    if len(files) > 10:
        raise HTTPException(status_code=400, detail="最多只能上传10个文件")
    
    results = []
    errors = []
    
    for file in files:
        try:
            # 验证文件
            validate_image(file)
            
            # 确保上传目录存在
            upload_dir = ensure_upload_dir()
            
            # 生成唯一文件名
            file_ext = Path(file.filename).suffix.lower()
            unique_filename = f"{uuid.uuid4().hex}{file_ext}"
            file_path = upload_dir / unique_filename
            
            # 读取文件内容
            contents = await file.read()
            
            # 检查文件大小
            if len(contents) > MAX_FILE_SIZE:
                errors.append({
                    "filename": file.filename,
                    "error": f"文件大小超过限制（最大 {MAX_FILE_SIZE / 1024 / 1024:.1f}MB）"
                })
                continue
            
            # 验证是否为有效图片
            try:
                image = Image.open(io.BytesIO(contents))
                image.verify()
            except Exception:
                errors.append({
                    "filename": file.filename,
                    "error": "无效的图片文件"
                })
                continue
            
            # 重新打开图片
            image = Image.open(io.BytesIO(contents))
            
            # 可选：压缩图片
            max_dimension = 2000
            if max(image.size) > max_dimension:
                image.thumbnail((max_dimension, max_dimension), Image.Resampling.LANCZOS)
                image.save(file_path, optimize=True, quality=85)
            else:
                with open(file_path, "wb") as f:
                    f.write(contents)
            
            # 返回文件URL
            file_url = f"/uploads/{unique_filename}"
            
            results.append({
                "url": file_url,
                "filename": unique_filename,
                "original_filename": file.filename,
                "size": len(contents)
            })
            
        except Exception as e:
            errors.append({
                "filename": file.filename,
                "error": str(e)
            })
    
    return {
        "success": results,
        "errors": errors,
        "total": len(files),
        "success_count": len(results),
        "error_count": len(errors)
    }

